/*
+--------------------------------------------------------------------------
|   Mblog [#RELEASE_VERSION#]
|   ========================================
|   Copyright (c) 2014, 2015 mtons. All Rights Reserved
|   http://www.mtons.com
|
+---------------------------------------------------------------------------
*/
package edu.whut.mall.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import edu.whut.mall.pojo.mapper.SecurityCodeMapper;
import edu.whut.mall.pojo.model.SecurityCode;
import edu.whut.mall.user.exception.MtonsException;
import edu.whut.mall.user.service.ISecurityCodeService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Date;


@Service
public class ISecurityCodeServiceImpl implements ISecurityCodeService {

    @Resource
    private SecurityCodeMapper securityCodeMapper;

    // 验证码存活时间 单位：分钟
    private int survivalTime = 30;

    @Override
    @Transactional
    public String generateCode(String target) {
        SecurityCode security = securityCodeMapper.selectOne(new LambdaQueryWrapper<SecurityCode>()
                .eq(SecurityCode::getTarget, target));
        String code = RandomStringUtils.randomNumeric(6);
        if (security == null) {
            security = new SecurityCode();
            security.setCreateTime(new Date());
            security.setExpired(DateUtils.addMinutes(new Date(), survivalTime));
            security.setCode(code);
            security.setTarget(target);
            security.setStatus(0);
            securityCodeMapper.insert(security);
        } else {
            long interval = (new Date().getTime() - security.getCreateTime().getTime()) / 1000;
            if (interval <= 60) {
                throw new MtonsException("发送间隔时间不能少于1分钟");
            }
            // 把 验证位 置0
            security.setStatus(0);
            security.setCreateTime(new Date());
            security.setExpired(DateUtils.addMinutes(new Date(), survivalTime));
            security.setCode(code);
            security.setTarget(target);
            securityCodeMapper.updateById(security);
        }
        return security.getCode();
    }

    @Override
    @Transactional
    public boolean verify(String target, String code) {
        Assert.hasLength(code, "验证码不能为空");
        SecurityCode security = securityCodeMapper.selectOne(new LambdaQueryWrapper<SecurityCode>()
                .eq(SecurityCode::getTarget, target)
                .eq(SecurityCode::getStatus, 0));
        Assert.notNull(security, "您没有进行过类型验证");
        Date now = new Date();
        Assert.state(now.getTime() <= security.getExpired().getTime(), "验证码已过期");
        Assert.isTrue(security.getStatus() == 0, "验证码已经使用过");
        if (code.equals(security.getCode())) security.setStatus(1);
        securityCodeMapper.updateById(security);
        return code.equals(security.getCode());
    }

}
